﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using Blog.TemplateEngine.Filters;
using Blog.TemplateEngine.Functions;

namespace Blog.TemplateEngine
{
    public class Engine
    {
        IDictionary<string, IFunction> mFunctions = new Dictionary<string, IFunction>(StringComparer.InvariantCultureIgnoreCase);
        IDictionary<string, IFilter> mFilters = new Dictionary<string, IFilter>(StringComparer.InvariantCultureIgnoreCase);
        string mTemplatePath;

        public Engine(string templatePath)
        {
            mTemplatePath = templatePath;

            RegisterFilter("ucase", new UCaseFilter());
            RegisterFilter("date", new DateFilter());

            RegisterFunction("for", new ForFunction());
            RegisterFunction("foreach", new ForEachFunction());
            RegisterFunction("now", new NowFunction());
            RegisterFunction("if", new IfFunction());
            RegisterFunction("ifnot", new IfNotFunction());
        }

        public void RegisterFilter(string name, IFilter filter)
        {
            mFilters[name] = filter;
        }

        public IFilter FindFilter(string name)
        {
            if (mFilters.ContainsKey(name))
                return mFilters[name];

            throw new TemplateException("Unknown filter: " + name);
        }

        public void RegisterFunction(string name, IFunction function)
        {
            mFunctions[name] = function;
        }

        public IFunction FindFunction(string name)
        {
            if (mFunctions.ContainsKey(name))
                return mFunctions[name];

            throw new TemplateException("Unknown function: " + name);
        }

        public Template CreateTemplateFromString(string source)
        {
            return new Template(source, this);
        }

        public Template CreateTemplateFromFile(string path)
        {
            if (!File.Exists(Path.Combine(mTemplatePath, path)))
            {
                throw new TemplateException("Could not find template '" + path + "'");
            }

            using (StreamReader file = File.OpenText(Path.Combine(mTemplatePath, path)))
            {
                return CreateTemplateFromString(file.ReadToEnd());
            }
        }
    }
}
